﻿using System;
using System.Collections.Specialized;
using System.Globalization;
using System.Web;
using Peter.Sdw.Data;

namespace Peter.Sdw.Logic
{
   /// <summary>
   /// View model for an entry.
   /// </summary>
   public class EntryModel : BaseModel, IStyleable
   {
      private string m_Text;
      private int m_EndIndex;
      private int m_StartIndex;
      private readonly StyleModel m_StyleModel;

      /// <summary>
      /// Initializes a new header.
      /// </summary>
      public EntryModel ()
         : base (null)
      {
         this.m_StyleModel = new StyleModel (this);
      }

      /// <summary>
      /// Gets or Sets the text of the header.
      /// </summary>
      public string Text
      {
         get { return m_Text; }
         set
         {
            this.m_Text = value;
            this.RaisePropertyChanged("Text");
         }
      }

      /// <summary>
      /// Gets or Sets the currently selected start index.
      /// </summary>
      public int StartIndex
      {
         get { return this.m_StartIndex; }
         set
         {
            this.m_StartIndex = value;
            this.RaisePropertyChanged ("StartIndex");
         }
      }

      /// <summary>
      /// Gets or Sets the currently selected end index.
      /// </summary>
      public int EndIndex
      {
         get { return this.m_EndIndex; }
         set
         {
            this.m_EndIndex = value;
            this.RaisePropertyChanged ("EndIndex");
         }
      }

      /// <summary>
      /// Gets the parent id.
      /// </summary>
      public int ParentId { get; private set; }

      /// <summary>
      /// Gets the item type.
      /// </summary>
      public ItemType ItemType { get; private set; }

      /// <summary>
      /// Gets the style input model.
      /// </summary>
      public StyleModel StyleInput { get { return this.m_StyleModel; } }

      /// <summary>
      /// Gets the header data from the server.
      /// </summary>
      public void Get (ItemType type, int parentId)
      {
         this.IsLoading = true;
         this.ItemType = type;
         this.ParentId = parentId;
         this.StyleInput.Styles.Clear ();
         this.StyleInput.CanSpan = type != ItemType.Chapter;
         WebQueue.Instance.WebGetComplete += this.OnGetCompleted;
         WebQueue.Instance.Get (string.Format (Constants.URL_GET_HEADER, this.ItemType, this.ParentId));
      }

      /// <summary>
      /// Adds the given passages to the current list.
      /// </summary>
      /// <param name="response"></param>
      private void AddStyles (dynamic response)
      {
         if (response.styles != null) {
            foreach (var style in response.styles) {
               this.StyleInput.Styles.Add (new Style {
                  Id = style.id,
                  Start = style.start,
                  End = style.end,
                  StartIndex = style.startindex,
                  EndIndex = style.endindex,
                  SpansMultiple = style.multispan
               });
            }
         }
      }

      /// <summary>
      /// Adds the given style.
      /// </summary>
      /// <param name="style">The style to add.</param>
      public void AddStyle (Style style)
      {
         var parameters = new NameValueCollection {
               {Constants.REQUEST_TOKEN, WebQueue.Instance.RequestToken},
               {"itemId", this.ParentId.ToString (CultureInfo.InvariantCulture)},
               {"startStyle", HttpUtility.UrlEncode (style.Start)},
               {"endStyle", HttpUtility.UrlEncode (style.End)},
               {"spansMultiple", style.SpansMultiple.ToString ()},
               {"startIndex", style.StartIndex.ToString (CultureInfo.InvariantCulture)},
               {"endIndex", style.EndIndex.ToString (CultureInfo.InvariantCulture)}
            };
         WebQueue.Instance.WebPostComplete += this.OnPostCompleted;
         WebQueue.Instance.Post (string.Format (Constants.URL_CREATE_STYLE, this.ItemType, "Header"), parameters);
      }

      /// <summary>
      /// Removes the given style.
      /// </summary>
      /// <param name="style">The style to remove.</param>
      public void RemoveStyle (Style style)
      {
         var parameters = new NameValueCollection {
               {Constants.REQUEST_TOKEN, WebQueue.Instance.RequestToken},
               {"id", style.Id.ToString (CultureInfo.InvariantCulture)},
               {"itemId", this.ParentId.ToString (CultureInfo.InvariantCulture)}
            };
         WebQueue.Instance.WebPostComplete += this.OnPostCompleted;
         WebQueue.Instance.Post (string.Format (Constants.URL_DELETE_STYLE, this.ItemType, "Header"), parameters);
      }

      /// <summary>
      /// Posts edits for the given style.
      /// </summary>
      /// <param name="style">The style to edit.</param>
      public void EditStyle (Style style)
      {
         var parameters = new NameValueCollection {
               {Constants.REQUEST_TOKEN, WebQueue.Instance.RequestToken},
               {"id", style.Id.ToString (CultureInfo.InvariantCulture)},
               {"itemId", this.ParentId.ToString (CultureInfo.InvariantCulture)},
               {"startStyle", HttpUtility.UrlEncode (style.Start)},
               {"endStyle", HttpUtility.UrlEncode (style.End)},
               {"spansMultiple", style.SpansMultiple.ToString ()},
               {"startIndex", style.StartIndex.ToString (CultureInfo.InvariantCulture)},
               {"endIndex", style.EndIndex.ToString (CultureInfo.InvariantCulture)}
            };
         WebQueue.Instance.WebPostComplete += this.OnPostCompleted;
         WebQueue.Instance.Post (string.Format (Constants.URL_EDIT_STYLE, this.ItemType, "Header"), parameters);
      }

      /// <summary>
      /// Occurs when a web request is completed.
      /// </summary>
      /// <param name="sender">WebQueue.</param>
      /// <param name="e">WebRequestEventArgs</param>
      private void OnGetCompleted (object sender, WebRequestEventArgs e)
      {
         try {
            if (e.Url == string.Format (Constants.URL_GET_HEADER, this.ItemType, this.ParentId)) {
               WebQueue.Instance.WebGetComplete -= this.OnGetCompleted;
               if (e.Response.status == Constants.SUCCESS) {
                  this.Text = e.Response.text;
                  this.AddStyles (e.Response);
               }
               this.IsLoading = false;
            }
         } catch (Exception ex) {
            Console.Error.WriteLine (ex.Message);
         }
      }

      /// <summary>
      /// Occurs when a web post request is completed.
      /// </summary>
      /// <param name="sender">WebQueue.</param>
      /// <param name="e">WebRequestEventArgs</param>
      private void OnPostCompleted (object sender, WebRequestEventArgs e)
      {
         if (e.Url == Constants.URL_EDIT_CHAPTER) {
            WebQueue.Instance.WebPostComplete -= this.OnPostCompleted;
            if (e.Response.status == Constants.SUCCESS) {
               
            }
         }
      }
   }
}
